import java.util.Scanner;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import javax.swing.UIManager;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Laurens
 */
public class inLine_Assignment_Refactor implements RefactoringMethod
{
    /*
     * Initialization and declaration of variables
     */
    String variable = " ";
    characterList characters = new characterList();    
    characterEditor characterEditor = new characterEditor();    
    String type = " ";
    FileEditor fileE = new FileEditor();
    /*
     * End of initialization and declaration of variables
     */
    
    /**
     * Constructor does nothing
     */
    public inLine_Assignment_Refactor()
    {
        //DOES NOTHING
    }

    /**
     * This does the actual inLine assignment of a method refactoring
     * @param parameters
     * @return 
     */
    @Override
    public Vector<String> refactor(Vector<String> parameters)
    {
        /*
         * Creates same look and feel for GUI
         */
        try 
        {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } 
        catch (Exception ex) 
        {
            Logger.getLogger(Rename_Parameter_Refactor.class.getName()).log(Level.SEVERE, null, ex);
        } 
        Vector<String> result = new Vector<String>();
        String path = "";
        boolean keywords = false;
        boolean punctuation = false;
        String file = " ";
        String s = " ";
        /*
         * Parameters declaration
         */
        if(parameters.size() > 0)
        {
            if(parameters.get(1) == null)
            {
                variable = JOptionPane.showInputDialog("What variable would you like to change into inLine assignment?\n");
            }
            else
            {
                variable = parameters.get(1);
            }
            path = parameters.get(0);
            result.add(path);
            keywords = characters.checkKeywords(variable);
            punctuation = characters.punctuationCheck(variable);
            if(punctuation)
            {
                result.add("Error you may not use that word, it is a punctuation");
                return result;    
            }
            else if(keywords)
            {
                result.add("Error you may not use that word, it is a special keyword in java");
                return result;
            }
            else
            {
                try
                {
                    /*
                     * Reads the file needed to do the rename refactor
                     */
                    file = fileE.read(path);
                }
                catch(Exception e)
                {

                }
                result.add(doInLineConversion(file, variable));
            }
        }
        else
        {
            result.add("Error, not enough parameters!");
            return result;
        }
        return result;
    }

    /**
     * Converts the class into a class that has inLine assignment functionality
     * @param file
     * @param variable
     * @return 
     */
    private String doInLineConversion(String file, String variable) 
    {
        Scanner scanner = new Scanner(file);
        Vector<String> result = new Vector<String>();
        int i = 1;
        int j = lineNumber(file, variable);
        String newFunction = " ";
        Vector<Integer> lineNumbers = lineNumbers(file, variable);
        int openBrackets = 1;
        int closedBrackets = 0;
        if(j == 0)
        {
            return "Error that variable is not found";
        }
        while(scanner.hasNext())
        {
            String currentLine = scanner.nextLine();
            if(i == j)
            {
                StringTokenizer st = new StringTokenizer(currentLine, ";");
                newFunction = getFunctionName(st.nextToken()); //y+1;
                for(int k = 0; k < 17; k++)
                {
                    if(currentLine.contains(type+" "+variable+" ="))
                    {
                        currentLine = scanner.nextLine();
                        i++;
                    }
                    else if(currentLine.contains(type+" "+variable+" = "))
                    {
                        currentLine = scanner.nextLine();
                        i++;
                    }
                    else if(currentLine.contains(type+" "+variable+"= "))
                    {   
                        currentLine = scanner.nextLine();
                        i++;
                    }
                    else if(currentLine.contains(type+" "+variable+"="))
                    {
                        currentLine = scanner.nextLine();
                        i++;
                    }
                    else if(currentLine.contains(" "+characters.keywords().get(k)+" "))
                    {
                        result.add(currentLine);
                        currentLine = scanner.nextLine();
                        k = 0;
                        i++;
                    }
                    else if(currentLine.contains("}"))
                    {
                        closedBrackets++;
                    }
                    else if(currentLine.contains("{"))
                    {
                        openBrackets++;
                    }
                    else if(openBrackets == closedBrackets)
                    {
                        k = 17;
                    }
                }
                for(int u = 0; u < lineNumbers.size(); u++)
                {
                    result.add(getFunctionCalls(lineNumbers.get(u), file, variable, newFunction));
                }
            }
            else
            {
                boolean line = false;
                for(int p = 0; p < characters.characterListMethod().size(); p++)
                {
                    if(currentLine.contains(characters.characterListMethod().get(p)+variable))
                    {
                        line = true;
                        p = characters.characterListMethod().size();
                    }
                    else if(currentLine.contains(variable+characters.characterListMethod().get(p)))
                    {
                        line = true;
                        p = characters.characterListMethod().size();
                    }
                }
                if(!line)
                {
                    result.add(currentLine);
                }
            }
            i++;
        }
        String output = "";
        for(int y = 0; y < result.size(); y++)
        {
            output += result.get(y) + "\n";
        }
        return output;
    }
    
    /**
     * Gets the linenumber of the initialization of the variable
     * @param file
     * @param variable
     * @return 
     */
    public int lineNumber(String file, String variable)
    {
        Scanner scanner = new Scanner(file);
        int i = 1;
        int _lineNumber = 0;
        while(scanner.hasNext())
        {
            String currentLine = scanner.nextLine();
            for(int k = 0; k < 17; k++)
            {
                if(currentLine.contains(characters.keywords().get(k)+" "+variable+" ="))
                {
                    type = characters.keywords().get(k);
                    _lineNumber = i;
                    return _lineNumber;
                }    
                else if(currentLine.contains(" "+characters.keywords().get(k)+" "+variable+"="))
                {
                    type = characters.keywords().get(k);
                    _lineNumber = i;
                    return _lineNumber;
                }    
                else if(currentLine.contains(characters.keywords().get(k)+" "+variable+"="))
                {
                    type = characters.keywords().get(k);
                    _lineNumber = i;
                    return _lineNumber;
                }    
                else if(currentLine.contains(" "+characters.keywords().get(k)+" "+variable+" ="))
                {
                    type = characters.keywords().get(k);
                    _lineNumber = i;
                    return _lineNumber;
                }    
            }
            i++;
        }
        return _lineNumber;
    }

    /**
     * Returns the functionality after the equals
     * @param currentLine
     * @return 
     */
    private String getFunctionName(String currentLine) 
    {
        StringTokenizer st = new StringTokenizer(currentLine);
        String output = "";
        while(st.hasMoreTokens())
        {
            String current = st.nextToken();
            if(current.equals("="))
            {
                for(int i = 0; st.hasMoreTokens(); i++)
                {
                    output += st.nextToken();
                    return output;
                }
            }
        }
        return output;
    }

    /**
     * Returns a vector with all the lineNumbers that use variable
     * @param file
     * @param variable
     * @return 
     */
    public Vector<Integer> lineNumbers(String file, String variable)
    {
        Scanner scanner = new Scanner(file);
        Vector<Integer> result = new Vector<Integer>();
        int i = 1;
        while(scanner.hasNext())
        {
            String currentLine = scanner.nextLine();
            if(currentLine.contains(variable))
            {
                result.add(i);
            }
            i++;
        }
        Vector<Integer> lines = new Vector<Integer>();
        for(int y = 0; y < result.size(); y++)
        {
            if(y == 0)
            {
                
            }
            else
            {
                lines.add(result.get(y));
            }
        }
        return lines;
    }
    
    /**
     * Returns a vector with the string where the calls to the function have been changed
     * @param lineNumbers
     * @param file
     * @param variable
     * @param newFunction
     * @return 
     */
    private String getFunctionCalls(int lineNumbers, String file, String variable, String newFunction) 
    {
        Scanner scanner = new Scanner(file);
        Vector<String> result = new Vector<String>();
        int z = 0;
        int i = 1;
        while(scanner.hasNext())
        {
            String currentLine = scanner.nextLine();
            if(i == lineNumbers)
            {
                result.add(currentLine.replaceAll(variable, newFunction));
                z++;
            }
            i++;
        }
        String output = "";
        for(int q = 0; q < result.size(); q++)
        {
            output += result.get(q);
        }
        return output;
    }

    /**
     * Returns a description of the current refactoring method
     * @return 
     */
    @Override
    public String description() 
    {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}
